来自网络CSDN?
简单的给局部变换赋值通知设置dirty_为true。但在这里好像忘了点什么?对了,子节点。在这里我们并没有设置子节点的脏标记。我们可以在这里使用递归来设置子节点的脏标记,但这比较缓慢。相反我们可以在渲染时做一些聪明的事。来看:
复制代码 void GraphNode::render(Transform parentWorld,bool dirty) { dirty |= dirty_; if(dirty) { world_ = local_.combine(parentWorld); dirty_ = false; }
if(mesh_) renderMesh(mesh_,world_);
for(int i=0;i<numChildren_;++i)
{
children_[i]->render(world_,dirty);
} } 复制代码 在这里,我们在渲染之前判断脏标记,如果为“true”则重新计算世界变换,同时清除脏标记,否则直接使用之前缓存的世界变换。这里有个很聪明的技巧就是使用一个另一个dirty变量,这个变量与物体本身的脏标记进行或预算,然后再传递给子物体渲染,这样,只要父链中有一个节点设置的脏标记,则dirty就为true,然后再传递给子节点渲染,也就是说,只要父链中设置了脏标记,那么子节点就会重新计算世界变换。使用这个方法能避免我们在“setTransform”中递归的去改变子节点的脏标记。最终的结果就是我们想要的:修改一个节点的局部变换只是需要几条赋值语句。渲染世界时只计算了自上一帧以来最少的变动的世界变换。